package com.zlzlib.liblayoutmanager;


import android.content.Context;
import android.os.Parcelable;
import android.util.SparseArray;
import android.view.View;
import android.view.animation.Interpolator;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

import static androidx.recyclerview.widget.RecyclerView.NO_POSITION;

/**
 * @Desc:
 * @Copyright:
 * @DateTime: 2021/8/10 14:19
 * @Author zlz
 * @Version 1.0
 */
public abstract class BaseLayoutManager extends LinearLayoutManager {

    protected static final int INVALID_SIZE = Integer.MAX_VALUE;
    protected static final int DETERMINE_BY_MAX_AND_MIN = -1;
    protected static final float DEFAULT_SPEED = 1f;

    //滚动方向 不确定
    private static final int DIRECTION_NO_WHERE = -1;
    //滚动方向 前进
    private static final int DIRECTION_FORWARD = 0;
    //滚动方向 后退
    private static final int DIRECTION_BACKWARD = 1;
    //到底部距离 如果不设置默认都是居中
    private int mDistanceToBottom = INVALID_SIZE;
    //布局顺序是否 倒转
    private boolean mReverseLayout = false;
    //最终判断布局视图 是否倒转得标志   resolveShouldLayoutReverse() 得到值
    private boolean mShouldReverseLayout = false;
    //LayoutManager 从 RecyclerView 分离时是否会回收其子项。  配合RecycledViewPool 来缓存视图
    private boolean mRecycleChildrenOnDetach;
    //当 LayoutManager 需要滚动到某个位置时，它会设置此变量并请求一个布局，该布局将检查此变量并相应地重新布局。
    private int mPendingScrollPosition = NO_POSITION;
    private int mLeftItems;
    private int mRightItems;
    //保存当前item状态
    private SavedScrollState mPendingSavedState = null;
    //差速器
    private Interpolator mSmoothScrollInterpolator;
    //当前页面缓存
    private final SparseArray<View> positionCache = new SparseArray<>();
    //最大可见的item数量
    private int mMaxVisibleItemCount = DETERMINE_BY_MAX_AND_MIN;
    //是否启用滚动条
    private boolean mSmoothScrollbarEnabled = true;
    //中心靠前排列 为true 才会执行setViewElevation方法
    private boolean mEnableBringCenterToFront;
    //当前有焦点的视图
    private View currentFocusView;
    //滚动页面切换监听
    private PageChangeListener pageChangeListener;

    //是否 无限循环
    protected boolean isInfiniteLoop = false;
    //当前朝向
    protected int mOrientation;
    //记录 滚动时改变的属性偏移量
    protected float mOffset;
    //方向计算工具
    protected OrientationUtils orientationUtils;
    //每个item所占空间
    protected float mInterval;
    //子视图的大小
    protected int mDecoratedMeasurement;
    protected int mDecoratedMeasurementInOther;
    // 子视图相距父布局 两边空间的大小
    protected int mSpaceMain;
    protected int mSpaceInOther;
    //滑动的速度
    protected float moveSpeed = DEFAULT_SPEED;

    //设置每个item的所占空间
    protected abstract float setInterval();

    //通过偏移量设置当前view的属性变化
    protected abstract void setItemViewProperty(View itemView, float targetOffset);

    //滑动系数 控制滑动快慢的
    protected float getDistanceRatio() {
        if (moveSpeed == 0) return Float.MAX_VALUE;
        return 1 / moveSpeed;
    }

    protected float getMaxOffset() {
        return mShouldReverseLayout ? 0 : (getItemCount() - 1) * mInterval;
    }

    protected float getMinOffset() {
        return mShouldReverseLayout ? -(getItemCount() - 1) * mInterval : 0;
    }

    //计算当前移动到第几个item 通过偏移量和每一个item所占空间计算
    protected int getCurrentPositionOffset() {
        if (mInterval == 0) return 0;
        return Math.round(mOffset / mInterval);
    }

    //视图被移除的最大值
    protected float maxRemoveOffset() {
        return orientationUtils.getTotalSpace() - mSpaceMain;
    }

    //视图被移除的最小值
    protected float minRemoveOffset() {
        return -mDecoratedMeasurement - orientationUtils.getStartAfterPadding() - mSpaceMain;
    }

    //设置初始化一些你需要的值  在子类绘制之前
    protected void setValueUp() {
    }

    /**
     * @param itemView
     * @param targetOffset 当前偏移量
     * @return 设置视图的海拔
     */
    protected float setViewElevation(View itemView, float targetOffset) {
        return 0;
    }

    protected int calItemLeft(View itemView, float targetOffset) {
        return mOrientation == VERTICAL ? 0 : (int) targetOffset;
    }

    protected int calItemTop(View itemView, float targetOffset) {
        return mOrientation == VERTICAL ? (int) targetOffset : 0;
    }

    public BaseLayoutManager(Context context) {
        this(context, HORIZONTAL, false);
    }

    public BaseLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context);
        setOrientation(orientation);
        setReverseLayout(reverseLayout);
        setItemPrefetchEnabled(false);
    }

    @Override
    public boolean isAutoMeasureEnabled() {
        //设置自适应item高度
        return true;
    }

    @Override
    public boolean getRecycleChildrenOnDetach() {
        return mRecycleChildrenOnDetach;
    }

    @Override
    public void setRecycleChildrenOnDetach(boolean recycleChildrenOnDetach) {
        mRecycleChildrenOnDetach = recycleChildrenOnDetach;
    }

    @Override
    public void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycler) {
        super.onDetachedFromWindow(view, recycler);
        if (mRecycleChildrenOnDetach) {
            removeAndRecycleAllViews(recycler);
            recycler.clear();
        }
    }

    @Override
    public Parcelable onSaveInstanceState() {
        if (mPendingSavedState != null) {
            return new SavedScrollState(mPendingSavedState);
        }
        SavedScrollState savedState = new SavedScrollState();
        savedState.position = mPendingScrollPosition;
        savedState.offset = mOffset;
        savedState.isReverseLayout = mShouldReverseLayout;
        return savedState;
    }

    @Override
    public void onRestoreInstanceState(Parcelable state) {
        if (state instanceof SavedScrollState) {
            mPendingSavedState = new SavedScrollState((SavedScrollState) state);
            requestLayout();
        }
    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        //子视图布局的回调
        if (state.getItemCount() == 0) {
            removeAndRecycleAllViews(recycler);
            mOffset = 0;
            return;
        }
        ensureLayoutState();
        resolveShouldLayoutReverse();
        //递归查询当前需要操作的子视图
        View scrap = getMeasureView(recycler, state, 0);
        if (scrap == null) {
            removeAndRecycleAllViews(recycler);
            mOffset = 0;
            return;
        }
        //测量子视图
        measureChildWithMargins(scrap, 0, 0);
        //计算子视图的大小
        mDecoratedMeasurement = orientationUtils.getDecoratedMeasurement(scrap);
        mDecoratedMeasurementInOther = orientationUtils.getDecoratedMeasurementInOther(scrap);
        //总空间大小减去子视图大小的一半
        mSpaceMain = (orientationUtils.getTotalSpace() - mDecoratedMeasurement) / 2;
        //判断是否设置了底部 如果设置了就不用计算居中距离
        if (mDistanceToBottom == INVALID_SIZE) {
            mSpaceInOther = (orientationUtils.getTotalSpaceInOther() - mDecoratedMeasurementInOther) / 2;
        } else {
            mSpaceInOther = orientationUtils.getTotalSpaceInOther() - mDecoratedMeasurementInOther - mDistanceToBottom;
        }
        //计算每个子视图所占空间
        mInterval = setInterval();
        setValueUp();
        if (mInterval == 0) {
            mLeftItems = 1;
            mRightItems = 1;
        } else {
            mLeftItems = (int) Math.abs(minRemoveOffset() / mInterval) + 1;
            mRightItems = (int) Math.abs(maxRemoveOffset() / mInterval) + 1;
        }
        if (mPendingSavedState != null) {
            mShouldReverseLayout = mPendingSavedState.isReverseLayout;
            mPendingScrollPosition = mPendingSavedState.position;
            mOffset = mPendingSavedState.offset;
        }
        if (mPendingScrollPosition != NO_POSITION) {
            mOffset = mShouldReverseLayout ?
                    mPendingScrollPosition * -mInterval : mPendingScrollPosition * mInterval;
        }
        layoutItems(recycler);
    }

    @Override
    public void onLayoutCompleted(RecyclerView.State state) {
        super.onLayoutCompleted(state);
        mPendingSavedState = null;
        mPendingScrollPosition = NO_POSITION;
    }

    @Override
    public View findViewByPosition(int position) {
        final int itemCount = getItemCount();
        if (itemCount == 0) return null;
        for (int i = 0; i < positionCache.size(); i++) {
            final int key = positionCache.keyAt(i);
            if (key >= 0) {
                if (position == key % itemCount) return positionCache.valueAt(i);
            } else {
                int delta = key % itemCount;
                if (delta == 0) delta = -itemCount;
                if (itemCount + delta == position) return positionCache.valueAt(i);
            }
        }
        return null;
    }

    @Override
    public boolean onAddFocusables(@NonNull RecyclerView recyclerView, @NonNull ArrayList<View> views, int direction, int focusableMode) {
        //处理视图焦点
        final int currentPosition = getCurrentPosition();
        final View currentView = findViewByPosition(currentPosition);
        if (currentView == null) return true;
        if (recyclerView.hasFocus()) {
            final int movement = getMovement(direction);
            if (movement != DIRECTION_NO_WHERE) {
                final int targetPosition = movement == DIRECTION_BACKWARD ? currentPosition - 1 : currentPosition + 1;
                ScrollUtils.smoothScrollToPosition(recyclerView, this, targetPosition);
            }
        } else {
            currentView.addFocusables(views, direction, focusableMode);
        }
        return true;
    }

    @Override
    public View onFocusSearchFailed(View focused, int focusDirection, RecyclerView.Recycler recycler, RecyclerView.State state) {
        return null;
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
        final int offsetPosition;
        if (isInfiniteLoop) {
            final int currentPosition = getCurrentPosition();
            final int total = getItemCount();
            final int targetPosition;
            if (position < currentPosition) {
                int d1 = currentPosition - position;
                int d2 = total - currentPosition + position;
                targetPosition = d1 < d2 ? (currentPosition - d1) : (currentPosition + d2);
            } else {
                int d1 = position - currentPosition;
                int d2 = currentPosition + total - position;
                targetPosition = d1 < d2 ? (currentPosition + d1) : (currentPosition - d2);
            }
            offsetPosition = getOffsetToPosition(targetPosition);
        } else {
            offsetPosition = getOffsetToPosition(position);
        }
        if (mOrientation == VERTICAL) {
            recyclerView.smoothScrollBy(0, offsetPosition, mSmoothScrollInterpolator);
        } else {
            recyclerView.smoothScrollBy(offsetPosition, 0, mSmoothScrollInterpolator);
        }
    }

    @Override
    public void scrollToPosition(int position) {
        if (!isInfiniteLoop && (position < 0 || position >= getItemCount())) return;
        mPendingScrollPosition = position;
        mOffset = mShouldReverseLayout ? position * -mInterval : position * mInterval;
        requestLayout();
    }

    @Override
    public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
        //横向滑动
        if (mOrientation == VERTICAL) {
            return 0;
        }
        return scrollBy(dx, recycler, state);
    }

    @Override
    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
        //竖向滑动
        if (mOrientation == HORIZONTAL) {
            return 0;
        }
        return scrollBy(dy, recycler, state);
    }

    /**
     * @return 是否可以横向滑动
     */
    @Override
    public boolean canScrollHorizontally() {
        return mOrientation == HORIZONTAL;
    }

    /**
     * @return 是否可以纵向滑动
     */
    @Override
    public boolean canScrollVertically() {
        return mOrientation == VERTICAL;
    }

    @Override
    public int computeHorizontalScrollOffset(RecyclerView.State state) {
        return computeScrollOffset();
    }

    @Override
    public int computeVerticalScrollOffset(RecyclerView.State state) {
        return computeScrollOffset();
    }

    @Override
    public int computeHorizontalScrollExtent(RecyclerView.State state) {
        return computeScrollExtent();
    }

    @Override
    public int computeVerticalScrollExtent(RecyclerView.State state) {
        return computeScrollExtent();
    }

    @Override
    public int computeHorizontalScrollRange(RecyclerView.State state) {
        return computeScrollRange();
    }

    @Override
    public int computeVerticalScrollRange(RecyclerView.State state) {
        return computeScrollRange();
    }

    /**
     * 设置排列是从上到下从左到右 还是倒转
     *
     * @param reverseLayout 默认false 不倒转  true为倒转
     */
    @Override
    public void setReverseLayout(boolean reverseLayout) {
        assertNotInLayoutOrScroll(null);
        if (reverseLayout == mReverseLayout) {
            return;
        }
        mReverseLayout = reverseLayout;
        removeAllViews();
    }

    @Override
    public boolean getReverseLayout() {
        return mReverseLayout;
    }

    /**
     * 设置排列为横向还是纵向  默认为横向 HORIZONTAL
     *
     * @param orientation {@link #HORIZONTAL} or {@link #VERTICAL}
     */
    @Override
    public void setOrientation(int orientation) {
        if (orientation != HORIZONTAL && orientation != VERTICAL) {
            throw new IllegalArgumentException("无效方向:" + orientation);
        }
        assertNotInLayoutOrScroll(null);
        if (orientation == mOrientation) {
            return;
        }
        mOrientation = orientation;
        orientationUtils = null;
        mDistanceToBottom = INVALID_SIZE;
        removeAllViews();
    }

    @Override
    public int getOrientation() {
        return mOrientation;
    }

    @Override
    public void setSmoothScrollbarEnabled(boolean enabled) {
        mSmoothScrollbarEnabled = enabled;
    }

    @Override
    public void onAdapterChanged(RecyclerView.Adapter oldAdapter, RecyclerView.Adapter newAdapter) {
        removeAllViews();
        mOffset = 0;
    }

    public boolean isInfiniteLoop() {
        return isInfiniteLoop;
    }

    /**
     * 设置是否无限循环
     *
     * @param infiniteLoop true为无限循环   false为不是
     */
    public void setInfiniteLoop(boolean infiniteLoop) {
        assertNotInLayoutOrScroll(null);
        if (infiniteLoop == isInfiniteLoop) {
            return;
        }
        isInfiniteLoop = infiniteLoop;
        requestLayout();
    }

    //计算视图布局顺序。 （例如从头到尾或从头到尾）
    private void resolveShouldLayoutReverse() {
        //如果布局为竖直 或者 方向不是从右到左
        if (mOrientation == VERTICAL || !isLayoutRTL()) {
            mShouldReverseLayout = mReverseLayout;
        } else {
            mShouldReverseLayout = !mReverseLayout;
        }
    }

    //递归查找测量的view
    private View getMeasureView(RecyclerView.Recycler recycler, RecyclerView.State state, int index) {
        if (index >= state.getItemCount() || index < 0) return null;
        try {
            return recycler.getViewForPosition(index);
        } catch (Exception e) {
            return getMeasureView(recycler, state, index + 1);
        }
    }

    private int scrollBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
        if (getChildCount() == 0 || dy == 0) {
            return 0;
        }
        ensureLayoutState();
        int willScroll = dy;
        //计算真正滚动的距离
        float realDx = dy / getDistanceRatio();
        if (Math.abs(realDx) < 0.00000001f) {
            return 0;
        }
        //当前滚动到的位置
        float targetOffset = mOffset + realDx;
        //处理滚动边界  如果无限循环 则不进行处理
        if (!isInfiniteLoop && targetOffset < getMinOffset()) {
            willScroll -= (targetOffset - getMinOffset()) * getDistanceRatio();
        } else if (!isInfiniteLoop && targetOffset > getMaxOffset()) {
            willScroll = (int) ((getMaxOffset() - mOffset) * getDistanceRatio());
        }
        realDx = willScroll / getDistanceRatio();
        mOffset += realDx;
        //回收处理 并重新绘制
        layoutItems(recycler);
        return willScroll;
    }

    private void ensureLayoutState() {
        if (orientationUtils == null) {
            orientationUtils = OrientationUtils.createOrientationUtils(this, mOrientation);
        }
    }

    //设置每个子视图的大小
    private void layoutItems(RecyclerView.Recycler recycler) {
        detachAndScrapAttachedViews(recycler);
        positionCache.clear();
        final int itemCount = getItemCount();
        if (itemCount == 0) return;
        // 确保当前位置从 0 到 1
        final int currentPos = mShouldReverseLayout ? -getCurrentPositionOffset() : getCurrentPositionOffset();
        int start = currentPos - mLeftItems;
        int end = currentPos + mRightItems;
        // 处理最大可见计数
        if (useMaxVisibleCount()) {
            boolean isEven = mMaxVisibleItemCount % 2 == 0;
            if (isEven) {
                int offset = mMaxVisibleItemCount / 2;
                start = currentPos - offset + 1;
                end = currentPos + offset + 1;
            } else {
                int offset = (mMaxVisibleItemCount - 1) / 2;
                start = currentPos - offset;
                end = currentPos + offset + 1;
            }
        }
        if (!isInfiniteLoop) {
            if (start < 0) {
                start = 0;
                if (useMaxVisibleCount()) end = mMaxVisibleItemCount;
            }
            if (end > itemCount) end = itemCount;
        }
        float lastOrderWeight = Float.MIN_VALUE;
        for (int i = start; i < end; i++) {
            if (useMaxVisibleCount() || !removeCondition(getProperty(i) - mOffset)) {
                // 根据当前位置开始和结束，
                // 需要计算适配器位置
                int adapterPosition = i;
                if (i >= itemCount) {
                    adapterPosition %= itemCount;
                } else if (i < 0) {
                    int delta = (-adapterPosition) % itemCount;
                    if (delta == 0) delta = itemCount;
                    adapterPosition = itemCount - delta;
                }
                final View scrap = recycler.getViewForPosition(adapterPosition);
                measureChildWithMargins(scrap, 0, 0);
                resetViewProperty(scrap);
                //通过子视图下标 计算当前视图的实际偏移量位置
                final float targetOffset = getProperty(i) - mOffset;
                layoutScrap(scrap, targetOffset);
                final float orderWeight = mEnableBringCenterToFront ? setViewElevation(scrap, targetOffset) : adapterPosition;
                if (orderWeight > lastOrderWeight) {
                    addView(scrap);
                } else {
                    addView(scrap, 0);
                }
                if (i == currentPos) currentFocusView = scrap;
                lastOrderWeight = orderWeight;
                positionCache.put(i, scrap);
            }
        }
        currentFocusView.requestFocus();
    }

    private int computeScrollOffset() {
        if (getChildCount() == 0) {
            return 0;
        }
        if (!mSmoothScrollbarEnabled) {
            return !mShouldReverseLayout ? getCurrentPosition() : getItemCount() - getCurrentPosition() - 1;
        }
        final float realOffset = getOffsetOfRightAdapterPosition();
        return !mShouldReverseLayout ? (int) realOffset : (int) ((getItemCount() - 1) * mInterval + realOffset);
    }

    private int computeScrollExtent() {
        if (getChildCount() == 0) {
            return 0;
        }
        if (!mSmoothScrollbarEnabled) {
            return 1;
        }
        return (int) mInterval;
    }

    private int computeScrollRange() {
        if (getChildCount() == 0) {
            return 0;
        }
        if (!mSmoothScrollbarEnabled) {
            return getItemCount();
        }
        return (int) (getItemCount() * mInterval);
    }

    //是否启用最大可见数量
    private boolean useMaxVisibleCount() {
        return mMaxVisibleItemCount != DETERMINE_BY_MAX_AND_MIN;
    }

    //当前位置是否可以移除
    private boolean removeCondition(float targetOffset) {
        return targetOffset > maxRemoveOffset() || targetOffset < minRemoveOffset();
    }

    private float getProperty(int position) {
        return mShouldReverseLayout ? position * -mInterval : position * mInterval;
    }

    //设置旋转缩放透明为初始化
    private void resetViewProperty(View v) {
        v.setRotation(0);
        v.setRotationY(0);
        v.setRotationX(0);
        v.setScaleX(1f);
        v.setScaleY(1f);
        v.setAlpha(1f);
    }

    private void layoutScrap(View scrap, float targetOffset) {
        final int left = calItemLeft(scrap, targetOffset);
        final int top = calItemTop(scrap, targetOffset);
        if (mOrientation == VERTICAL) {
            layoutDecorated(scrap, mSpaceInOther + left, mSpaceMain + top,
                    mSpaceInOther + left + mDecoratedMeasurementInOther, mSpaceMain + top + mDecoratedMeasurement);
        } else {
            layoutDecorated(scrap, mSpaceMain + left, mSpaceInOther + top,
                    mSpaceMain + left + mDecoratedMeasurement, mSpaceInOther + top + mDecoratedMeasurementInOther);
        }
        setItemViewProperty(scrap, targetOffset);
    }

    /**
     * 计算正确的偏移量
     */
    private float getOffsetOfRightAdapterPosition() {
        if (mShouldReverseLayout)
            return isInfiniteLoop ? (mOffset <= 0 ? (mOffset % (mInterval * getItemCount())) :
                    (getItemCount() * -mInterval + mOffset % (mInterval * getItemCount()))) : mOffset;
        else
            return isInfiniteLoop ? (mOffset >= 0 ? (mOffset % (mInterval * getItemCount())) :
                    (getItemCount() * mInterval + mOffset % (mInterval * getItemCount()))) : mOffset;
    }

    private int getMovement(int direction) {
        if (mOrientation == VERTICAL) {
            if (direction == View.FOCUS_UP) {
                return mShouldReverseLayout ? DIRECTION_FORWARD : DIRECTION_BACKWARD;
            } else if (direction == View.FOCUS_DOWN) {
                return mShouldReverseLayout ? DIRECTION_BACKWARD : DIRECTION_FORWARD;
            } else {
                return DIRECTION_NO_WHERE;
            }
        } else {
            if (direction == View.FOCUS_LEFT) {
                return mShouldReverseLayout ? DIRECTION_FORWARD : DIRECTION_BACKWARD;
            } else if (direction == View.FOCUS_RIGHT) {
                return mShouldReverseLayout ? DIRECTION_BACKWARD : DIRECTION_FORWARD;
            } else {
                return DIRECTION_NO_WHERE;
            }
        }
    }

    /**
     * 用于居中当前视图 {@link CenterSnapUtils}
     *
     * @return 中心和当前位置之间的距离
     */
    public int getOffsetToCenter() {
        if (isInfiniteLoop)
            return (int) ((getCurrentPositionOffset() * mInterval - mOffset) * getDistanceRatio());
        return (int) ((getCurrentPosition() * (!mShouldReverseLayout ? mInterval : -mInterval) - mOffset) * getDistanceRatio());
    }

    public int getOffsetToPosition(int position) {
        //计算当前滑动的模块位置
        if (isInfiniteLoop) return (int) (((getCurrentPositionOffset() +
                (!mShouldReverseLayout ? position - getCurrentPositionOffset() : -getCurrentPositionOffset() - position)) *
                mInterval - mOffset) * getDistanceRatio());
        return (int) ((position * (!mShouldReverseLayout ? mInterval : -mInterval) - mOffset) * getDistanceRatio());
    }


    public int getCurrentPosition() {
        if (getItemCount() == 0) return 0;
        int position = getCurrentPositionOffset();
        if (!isInfiniteLoop) return Math.abs(position);
        position = !mShouldReverseLayout ?
                (position >= 0 ? position % getItemCount() : getItemCount() + position % getItemCount()) :
                (position > 0 ? getItemCount() - position % getItemCount() : -position % getItemCount());
        return position == getItemCount() ? 0 : position;
    }

    /**
     * @param v 子视图
     * @return 获得当前子视图的位置下标
     */
    public int getLayoutPositionOfView(View v) {
        for (int i = 0; i < positionCache.size(); i++) {
            int key = positionCache.keyAt(i);
            View value = positionCache.get(key);
            if (value == v) return key;
        }
        return -1;
    }

    public void setSmoothScrollInterpolator(Interpolator mSmoothScrollInterpolator) {
        this.mSmoothScrollInterpolator = mSmoothScrollInterpolator;
    }

    public int getMaxVisibleItemCount() {
        return mMaxVisibleItemCount;
    }

    public void setMaxVisibleItemCount(int mMaxVisibleItemCount) {
        assertNotInLayoutOrScroll(null);
        if (this.mMaxVisibleItemCount == mMaxVisibleItemCount) return;
        this.mMaxVisibleItemCount = mMaxVisibleItemCount;
        removeAllViews();
    }

    public void setEnableBringCenterToFront(boolean bringCenterToTop) {
        assertNotInLayoutOrScroll(null);
        if (mEnableBringCenterToFront == bringCenterToTop) {
            return;
        }
        this.mEnableBringCenterToFront = bringCenterToTop;
        requestLayout();
    }

    public boolean getEnableBringCenterToFront() {
        return mEnableBringCenterToFront;
    }

    public PageChangeListener getPageChangeListener() {
        return pageChangeListener;
    }

    public void setPageChangeListener(PageChangeListener pageChangeListener) {
        this.pageChangeListener = pageChangeListener;
    }

    public int getDistanceToBottom() {
        return mDistanceToBottom == INVALID_SIZE ?
                (orientationUtils.getTotalSpaceInOther() - mDecoratedMeasurementInOther) / 2 : mDistanceToBottom;
    }

    public void setDistanceToBottom(int mDistanceToBottom) {
        assertNotInLayoutOrScroll(null);
        if (this.mDistanceToBottom == mDistanceToBottom) return;
        this.mDistanceToBottom = mDistanceToBottom;
        removeAllViews();
    }


    public float getMoveSpeed() {
        return moveSpeed;
    }

    public void setMoveSpeed(float moveSpeed) {
        assertNotInLayoutOrScroll(null);
        if (this.moveSpeed == moveSpeed) return;
        this.moveSpeed = moveSpeed;
    }
}